

function myAxios() {
    // 管理拦截器和请求
    const managerInterceptors = [];
    let createOpts;
    const request = {
        use(callback) {
            managerInterceptors.unshift(callback);
        }
    }
    // 响应的拦截在请求后面
    const response = {
        use(callback) {
            managerInterceptors.push(callback);
        }
    }
    axios.interceptor = {
        request,
        response
    }
    function axios(options = {}) {
        const defaultOptions = {
            method: 'get',
            url: '',
            params: {}
        }

        options = Object.assign({}, defaultOptions, options);


        // 把请求放在第一位
        managerInterceptors.push(setRequest);
        // 请求前的拦截在请求前面


        // 开始处理请求拦截，请求得到结果，返回结果拦截
        let r;
        managerInterceptors.forEach(fn => {
            r = fn(options);
            // 如果拦截器返回的是promise实例，处理一下
            if (r instanceof Promise) {
                // 是promise实例
                r.then(config => {
                    r = config;
                })
            }
        })
        return new Promise((resolve, reject) => {
            resolve(r);
        })
        // 清空managerInterceptors
        managerInterceptors.length = 0;
    }


    ['get', 'post'].forEach(method => {
        axios[method] = (path, options) => {
            if (method === 'post') {
                let o = options
                options = {};
                options.data = o;
            }
            options.url = path;
            options.method = method;
            return setRequest(options);
        }
    })

    /**
     * 创建XMLHttpRequest对象，根据配置发送请求
     * @param {object} options
     */
    function setRequest(options) {
        if (createOpts) {
            // 如果有create传入的options， 进行合并
            options = Object.assign({}, createOpts, options);
            // 清空
            createOpts = null;
        }
        return new Promise((resolve, reject) => {
            try {
                let { method, url, params, data, baseURL, headers } = options;
                let postBody = null;
                if (data && method.toLowerCase() === 'post') {
                    postBody = JSON.stringify(data);
                }
                // 1创建对象
                const xhr = new XMLHttpRequest();
                // 处理get参数
                if (params && typeof params === 'object') {
                    url += '?';
                    for (let prop in params) {
                        url += `${prop}=${params[prop]}&`
                    }
                    url = url.slice(0, -1);
                }
                // 处理baseURL
                if (baseURL) {
                    url = baseURL + url;
                }
                // 2 配置
                xhr.open(method, url, true);
                // 处理header
                if (headers) {
                    for (let header in headers) {
                        xhr.setRequestHeader(header, headers[header]);
                    }
                }

                // 告诉浏览器，想要的头是json格式的
                // xhr.responseType = 'json';
                // 3 监听状态变化
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4) {
                        const responseHeader = xhr.getAllResponseHeaders()

                        if (xhr.status >= 200 && xhr.status <= 300) {
                            resolve({
                                header: parseHeader(responseHeader),
                                data: JSON.parse(xhr.responseText || xhr.response),
                                statusText: xhr.statusText,
                                status: xhr.status,
                                config: options,
                                request: xhr
                            })
                        }
                    }
                }
                // 4 发送
                xhr.send(postBody);
            } catch (e) {
                reject(e);
            }

        })
    }

    /** 
     *解析响应头
     */
    function parseHeader(headers) {
        const obj = {};
        headers.split('\r\n').slice(0, -1).forEach(item => {
            const header = item.split(': ');
            obj[header[0]] = header[1];
        })
        return obj;
    }

    axios.create = function (options) {
        createOpts = options;
        return setRequest;
    }

    return axios;
}


let axios = myAxios();






